<template>
  <div>
    <h4>简易protobuff解码工具</h4>
    选择编码的消息

    <el-select
      v-model="selected"
      filterable
      placeholder="请选择消息类型"
      @blur="searchBlur"
    >
      <el-option
        v-for="item in options"
        :label="item.text"
        :key="item.text"
        :value="item.value"
      >
      </el-option>
    </el-select>

    <br /><br />
    <div style="display: flex; flex-flow: row">
      <div style="display: flex; flex-flow: column; width: 50%; padding: 5px">
        <el-input
          type="textarea"
          v-model="pb"
          placeholder="输入pb定义"
          rows="24"
        ></el-input>
      </div>
      <div style="display: flex; flex-flow: column; width: 50%; padding: 5px">
        <el-input
          type="textarea"
          v-model="data"
          placeholder="输入数据JSON [1,2,3] 或 {0:1,1:2,2:3} 格式"
          rows="24"
        ></el-input>
      </div>
    </div>
    <h4>{{ decoded }}</h4>
  </div>
</template>

<script>
var protobuf = require("protobufjs");
const dumptype = (root, path, r) => {
  if (root.nested) {
    Object.values(root.nested).forEach((v) => {
      dumptype(v, root.name ? `${path}.${root.name}` : path, r);
    });
  } else {
    if (root.fields) {
      r.push({ text: root.name ? `${path}.${root.name}` : path, value: root });
    }
  }
};
export default {
  name: "pbtool",
  data() {
    return {
      pb: "",
      data: "",
      selected: null,
    };
  },
  computed: {
    decoded: function () {
      if (this.selected && this.data) {
        try {
          const data = JSON.parse(this.data);
          if (Array.isArray(data)) {
            const msgData = new Uint8Array(data);
            return this.selected.decode(msgData);
          } else {
            const msgData = new Uint8Array(Object.keys(data).length);
            Object.keys(data).forEach((k) => {
              msgData[k] = data[k];
            });
            return this.selected.decode(msgData);
          }
        } catch (e) {
          return e;
        }
      } else {
        return "左侧输入pb定义，右侧输入数据，顶部选择消息类型";
      }
    },
    options: function () {
      if (this.pb) {
        try {
          const json = JSON.parse(this.pb);
          const result = [];
          dumptype(protobuf.Root.fromJSON(json), "", result);
          return result;
        } catch (e) {
          try {
            const r = protobuf.parse(this.pb);
            const result = [];
            dumptype(r.root, "", result);
            return result;
          } catch (e) {
            return e;
          }
        }
      } else {
        return [{ text: "先输入PB消息定义", value: null }];
      }
    },
  },
  methods: {
    searchBlur(e) {
      this.value = e.target.value;
    },
  },
};
</script>
